/*
 * Copyright (C) 2012 CNL - ECE Dept - National University of Singapore
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package sg.nus.ece.cnl.veracity.hadoop.generator;

import java.io.InputStream;
import java.io.StringWriter;
import java.util.Properties;
import org.apache.commons.io.IOUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.runtime.resource.loader.StringResourceLoader;
import org.apache.velocity.runtime.resource.util.StringResourceRepository;

/**
 *
 * @author tram
 */
public class VelocityUtil {
    
    // velocity template
    private Template template;
    // velocity context
    private VelocityContext context;

    public VelocityUtil(String templatePath) throws java.lang.Exception {

        Properties properties = new Properties();
        properties.setProperty("resource.loader", "string");
        properties.setProperty("string.resource.loader.class", "org.apache.velocity.runtime.resource.loader.StringResourceLoader");
        properties.setProperty("string.resource.loader.repository.class", "org.apache.velocity.runtime.resource.util.StringResourceRepositoryImpl");

        Velocity.init(properties);
        if (!Velocity.resourceExists(templatePath)) {
            StringResourceRepository repo = StringResourceLoader.getRepository();
            repo.putStringResource(templatePath, getTemplateFromResource(templatePath));
        }

        template = Velocity.getTemplate(templatePath);
        context = new VelocityContext();
    }

    /**
     * Adds data to the context.
     *
     * @param key
     * @param value
     */
    public void put(String key, Object value) {

        context.put(key, value);
    }

    /**
     * Renders the template into a StringWriter.
     *
     * @return a StringWriter object containing the context value merged into
     * template
     * @throws sg.nus.ece.cnl.veracity.exception.VeracityException
     */
    public StringWriter merge()
            throws sg.nus.ece.cnl.veracity.exception.VeracityException {

        try {
            StringWriter writer = new StringWriter();
            template.merge(context, writer);

            return writer;

        } catch (org.apache.velocity.exception.ResourceNotFoundException ex) {
            throw new sg.nus.ece.cnl.veracity.exception.VeracityException(ex);
        } catch (org.apache.velocity.exception.ParseErrorException ex) {
            throw new sg.nus.ece.cnl.veracity.exception.VeracityException(ex);
        } catch (org.apache.velocity.exception.MethodInvocationException ex) {
            throw new sg.nus.ece.cnl.veracity.exception.VeracityException(ex);
        } catch (java.io.IOException ex) {
            throw new sg.nus.ece.cnl.veracity.exception.VeracityException(ex);
        }
    }
    
     /**
     * Getting the template from Resource of the project
     * @param templatePath template path
     * @return the string representing the template
     */
    private String getTemplateFromResource(final String templatePath) {

        try {
            InputStream stream = ClassLoader.getSystemResourceAsStream(templatePath);
            return IOUtils.toString(stream, "UTF-8");

        } catch (java.io.IOException ex) {
            throw new RuntimeException(ex);
        }
    }
}
